package cn.aws360.boot.wechat.biz.service.impl;

import cn.aws360.boot.base.api.constant.enums.DelFlagEnum;
import cn.aws360.boot.base.api.exception.ServiceException;
import cn.aws360.boot.data.api.constant.DataConstant;
import cn.aws360.boot.data.api.factory.PageFactory;
import cn.aws360.boot.data.api.pojo.request.PageQuery;
import cn.aws360.boot.data.api.pojo.response.PageResult;
import cn.aws360.boot.data.api.utils.PojoUtils;
import cn.aws360.boot.wechat.api.constant.WxmConstant;
import cn.aws360.boot.wechat.api.exception.WxmExceptionEnum;
import cn.aws360.boot.wechat.api.pojo.request.WxmCorpusQuery;
import cn.aws360.boot.wechat.api.pojo.request.WxmCorpusWrite;
import cn.aws360.boot.wechat.api.pojo.response.WxmCorpusModel;
import cn.aws360.boot.wechat.biz.domain.WxmCorpus;
import cn.aws360.boot.wechat.biz.mapper.WxmCorpusMapper;
import cn.aws360.boot.wechat.biz.service.WxmCorpusService;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author junnan
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class WxmCorpusServiceImpl extends ServiceImpl<WxmCorpusMapper, WxmCorpus> implements WxmCorpusService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = WxmConstant.MODULE_WXM_CORPUS_CACHE, allEntries = true)
    public Boolean add(WxmCorpusWrite wxmCorpusWrite) {
        WxmCorpus wxmCorpus = BeanUtil.copyProperties(wxmCorpusWrite, WxmCorpus.class, DataConstant.ID);
        return this.save(wxmCorpus);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = WxmConstant.MODULE_WXM_CORPUS_CACHE, allEntries = true)
    public Boolean edit(WxmCorpusWrite wxmCorpusWrite) {
        WxmCorpus wxmCorpus = this.getWxCorpusById(wxmCorpusWrite.getId());
        BeanUtil.copyProperties(wxmCorpusWrite, wxmCorpus);
        return this.updateById(wxmCorpus);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = WxmConstant.MODULE_WXM_CORPUS_CACHE, allEntries = true)
    public Boolean remove(String ids) {
        List<Integer> corpusIdList = Convert.toList(Integer.class, ids.split(StrUtil.COMMA));
        return this.removeByIds(corpusIdList);
    }

    @Override
    public WxmCorpusModel detail(Integer id) {
        WxmCorpus wxmCorpus = this.getWxCorpusById(id);
        return BeanUtil.copyProperties(wxmCorpus, WxmCorpusModel.class);
    }

    @Override
    public List<WxmCorpusModel> findList(WxmCorpusQuery wxmCorpusQuery) {
        LambdaQueryWrapper<WxmCorpus> queryWrapper = createQueryWrapper(wxmCorpusQuery);
        List<WxmCorpus> wxmCorpusList = this.list(queryWrapper);
        return PojoUtils.copyToList(wxmCorpusList, WxmCorpusModel.class);
    }

    @Override
    public PageResult<WxmCorpusModel> findPage(WxmCorpusQuery wxmCorpusQuery, PageQuery pageQuery) {
        LambdaQueryWrapper<WxmCorpus> queryWrapper = createQueryWrapper(wxmCorpusQuery);
        PageResult<WxmCorpus> wxCorpusPage = PageFactory.getPageResult(this, pageQuery, queryWrapper);
        return PojoUtils.copyToPage(wxCorpusPage, WxmCorpusModel.class);
    }

    private WxmCorpus getWxCorpusById(Integer id) {
        WxmCorpus wxmCorpus = this.getById(id);
        checkNotExist(wxmCorpus);
        return wxmCorpus;
    }

    private LambdaQueryWrapper<WxmCorpus> createQueryWrapper(WxmCorpusQuery wxmCorpusQuery) {
        return Wrappers.<WxmCorpus>lambdaQuery()
                .eq(StrUtil.isNotBlank(wxmCorpusQuery.getAppId()), WxmCorpus::getAppId, wxmCorpusQuery.getAppId())
                .eq(StrUtil.isNotBlank(wxmCorpusQuery.getInput()), WxmCorpus::getInput, wxmCorpusQuery.getInput())
                .orderByDesc(WxmCorpus::getOutLevel);
    }

    private void checkNotExist(WxmCorpus wxmCorpus) {
        if (ObjectUtil.isNull(wxmCorpus) || DelFlagEnum.Y.getValue().equals(wxmCorpus.getDelFlag())) {
            throw new ServiceException(WxmExceptionEnum.WXM_CORPUS_NOT_EXIST);
        }
    }

}
